<?php
/**
 * Created by JetBrains PhpStorm.
 * User: Bezdelnick
 * Date: 23.03.13
 * Time: 18:09
 * To change this template use File | Settings | File Templates.
 */
$PATH = Config::getInstance()->getBasePath();
require_once("$PATH/util/PatternUtil.php");
require_once("$PATH/controller/AbstractController.php");

abstract class AbstractDao
{
    const LOAD_ALL_OBJECTS = "SELECT #columns# FROM #table_name#";
    const GET_OBJECT_BY_ID = "SELECT #columns# FROM #table_name# WHERE #condition#";
    const INSERT_OBJECT = "INSERT INTO #table_name# (#columns#) VALUES (#values#)";
    const UPDATE_OBJECT = "UPDATE #table_name# SET #set_values# WHERE #condition#";
    const DELETE_OBJECT = "DELETE FROM #table_name# WHERE #condition#";

    protected $controller;

    public function load()
    {
        // Build map for replacing
        $mapping = array(
            "columns" => PatternUtil::getInstance()->getColumns($this->controller),
            "table_name" => $this->controller->getTableName()
        );

        // Create query
        $query = PatternUtil::getInstance()->merge(self::LOAD_ALL_OBJECTS, $mapping);

        // Load data from database
        $result = mysql_query(
            $query, Config::getInstance()->getDbConnection()
        );

        // Build object's array
        $instances = array();
        while ($row = mysql_fetch_array($result)) {
            $instance = PatternUtil::getInstance()->getObjectFromArray(
                $this->controller, $row);
            array_push($instances, $instance);

            /*var_dump($instance);
            echo "<br/>";*/
        }
        return $instances;
    }

    public function getById($id)
    {
        //Prepare instance
        $instance = $this->controller->getNewCopyOfObject();
        $setterName = "set" . $this->controller->getIdMapping()->getFieldName();
        $instance->$setterName($id);

        //var_dump($instance);

        // Build map for replacing
        $mapping = array(
            "columns" => PatternUtil::getInstance()->getColumns($this->controller),
            "table_name" => $this->controller->getTableName(),
            "condition" => PatternUtil::getInstance()->getColumnSetupWithValue(
                $instance, $this->controller->getIdMapping()
            )
        );

        // Create query
        $query = PatternUtil::getInstance()->merge(self::GET_OBJECT_BY_ID, $mapping);
        //echo $query;

        // Load data from database
        $result = mysql_query(
            $query, Config::getInstance()->getDbConnection()
        );
        $row = mysql_fetch_array($result);
        $instance = PatternUtil::getInstance()->getObjectFromArray(
            $this->controller, $row);
        return $instance;
    }

    public function insert($instance)
    {
        $columnsAndValues = PatternUtil::getInstance()->getColumnsAndValuesWhereValueNotNull(
            $instance, $this->controller->getMappings());

        // Build map for replacing
        $mapping = array(
            "table_name" => $this->controller->getTableName(),
            "columns" => $columnsAndValues[0],
            "values" => $columnsAndValues[1]
        );

        // Create query
        $query = PatternUtil::getInstance()->merge(self::INSERT_OBJECT, $mapping);

        // Send to database
        mysql_query($query, Config::getInstance()->getDbConnection());

        return mysql_insert_id();
    }

    public function update($instance)
    {
        // Build map for replacing
        $mapping = array(
            "table_name" => $this->controller->getTableName(),
            "set_values" => PatternUtil::getInstance()->getColumnsSetupWithValues(
                $instance, $this->controller->getMappings(), ", "),
            "condition" => PatternUtil::getInstance()->getColumnSetupWithValue(
                $instance, $this->controller->getIdMapping(), " AND ")
        );

        // Create query
        $query = PatternUtil::getInstance()->merge(self::UPDATE_OBJECT, $mapping);
        //echo $query . "<br/>";

        // Send to database
        mysql_query($query, Config::getInstance()->getDbConnection());
    }

    public function delete($id)
    {
        $instance = $this->controller->getNewCopyOfObject();
        $instance->setId($id);

        // Build map for replacing
        $mapping = array(
            "table_name" => $this->controller->getTableName(),
            "condition" => PatternUtil::getInstance()->getColumnSetupWithValue(
                $instance, $this->controller->getIdMapping(), "")
        );

        // Create query
        $query = PatternUtil::getInstance()->merge(self::DELETE_OBJECT, $mapping);

        // Send to database
        mysql_query($query, Config::getInstance()->getDbConnection());
    }
}
